﻿using AiMoBridge.Interface;
using AiMoBridge.Interface.Client;
using AiMoWindows.CodeScripts;
using AiMoWindows.CodeScripts.IO;
using AiMoWindows.Entrance;
using AiMoWindows.Localization;
using AiMoWindows.MainActions.Mode;
using AiMoWindows.MainActions.SecondaryActions;
using AiMoWindows.Windows;
using System.IO;
using System.Windows;

namespace AiMoWindows.MainActions
{
    static class WindowStarter
    {
        public static void ShowInRandomLocation(this Window window)
        {
            if (AiMoProgram.Instance.GetLastScriptWindowsBounds(out Rect bounds))
            {
                Random random = new Random();
                int count = random.Next(20, 60);
                window.Left = bounds.Left + count;
                window.Top = bounds.Top - count;
                window.Width = bounds.Width;
                window.Height = bounds.Height;
                window.Show();
            }
            else
            {
                Random random = new Random();
                window.Left = random.Next(100, 1080);
                window.Top = random.Next(100, 500);
                window.Show();
            }
        }
        /// <summary>
        /// 直接打开AiMo窗口
        /// </summary>
        public static IAiMoWindow OpenNewScriptWindow(IExecutor? executeScripts, bool emptyScripts)
        {
            ScriptComplileMode mode = (AiMoProgram.Instance.AiMoExecuterMode == ExecuterMode.Grasshopper) ?
                ScriptComplileMode.GrasshopperScript :
                ScriptComplileMode.RhinoScript;
            ScriptSource scriptSource = new ScriptSource(mode, null, emptyScripts);
            ScriptManager currentScript = new ScriptManager(executeScripts, scriptSource, "");
            Windows.Scripts.ScriptWindow scriptWindow = new Windows.Scripts.ScriptWindow(currentScript);
            ShowInRandomLocation(scriptWindow);
            scriptWindow.InitializeEditor();

            return scriptWindow;
        }
        /// <summary>
        /// OpenNewScriptWindow from file path
        /// </summary>
        /// <exception cref="Exception">Open Error</exception>
        public static IAiMoWindow OpenNewScriptWindow(IExecutor? executeScripts, string filePath)
        {
            if (!File.Exists(filePath)) throw new Exception(Local.Get("File not exist ") + filePath);
            byte[] bytes = File.ReadAllBytes(filePath);
            ScriptComplileMode mode = (AiMoProgram.Instance.AiMoExecuterMode == ExecuterMode.Grasshopper) ?
                ScriptComplileMode.GrasshopperScript :
                ScriptComplileMode.RhinoScript;
            ScriptSource scriptSource = new ScriptSource(mode, null, true);
            if (!CodeIO.FromBytes(bytes, scriptSource, out string error))
            {
                throw new Exception(error);
            }
            ScriptManager currentScript = new ScriptManager(executeScripts, scriptSource, filePath);
            string printInfo = Local.Get("Opened code from:") + Environment.NewLine + Path.GetFileName(filePath);
            Windows.Scripts.ScriptWindow scriptWindow = new Windows.Scripts.ScriptWindow(currentScript);
            ShowInRandomLocation(scriptWindow);
            scriptWindow.InitializeEditor();
            scriptWindow.PrintDebug(printInfo);

            if (scriptSource.ScriptsMode == ScriptComplileMode.RhinoScript && AiMoProgram.Instance.AiMoExecuterMode == ExecuterMode.Grasshopper)
            {
                MessageBox.Show(scriptWindow, Local.Get("You are opening a Rhino command AiMoScript in AiMo Grasshopper.\nThe code cannot be send to run in Grasshopper."), Local.Get("Warning"));
            }
            else if (scriptSource.ScriptsMode == ScriptComplileMode.GrasshopperScript && AiMoProgram.Instance.AiMoExecuterMode == ExecuterMode.Rhino)
            {
                MessageBox.Show(scriptWindow, Local.Get("You are opening a Grasshopper C# Component AiMoScript in AiMo Rhino.\nThe code cannot be send to run as a Rhino Command."), Local.Get("Warning"));
            }
            return scriptWindow;
        }

        /// <summary>
        /// OpenNewScriptWindow from download
        /// </summary>
        /// <exception cref="Exception">Open Error</exception>
        public static IAiMoWindow OpenNewScriptWindow(IExecutor? executeScripts, ScriptDownloadResult downloadResult)
        {
            ScriptSource scriptSource = new ScriptSource(ScriptComplileMode.RhinoScript, null, true);
            downloadResult.SyncToScriptSource(scriptSource);
            ScriptManager currentScript = new ScriptManager(executeScripts, scriptSource, "");
            string printInfo = Local.Get("Downloaded code from:") + downloadResult.ShareKey;
            if (!string.IsNullOrEmpty(downloadResult.SyncToScriptInfo)) printInfo += Environment.NewLine + downloadResult.SyncToScriptInfo;
            Windows.Scripts.ScriptWindow scriptWindow = new Windows.Scripts.ScriptWindow(currentScript);
            ShowInRandomLocation(scriptWindow);
            scriptWindow.InitializeEditor();
            scriptWindow.PrintDebug(printInfo);
            return scriptWindow;
        }

        public static IAiMoWindow OpenNewScriptWindow(IExecutor? executeScripts, IScriptMessage message)
        {
#warning WIP AiMo 的AI要兼容Aimo GH
            ScriptSource scriptSource = new ScriptSource(ScriptComplileMode.RhinoScript, null, true);
            InitScriptFromAI(scriptSource, message);
            ScriptManager currentScript = new ScriptManager(executeScripts, scriptSource, "");
            Windows.Scripts.ScriptWindow scriptWindow = new Windows.Scripts.ScriptWindow(currentScript);
            ShowInRandomLocation(scriptWindow);
            scriptWindow.InitializeEditor();
            return scriptWindow;
        }
        static void InitScriptFromAI(ScriptSource scriptSource, IScriptMessage message)
        {

            if (message.Valid)
            {
                if (!string.IsNullOrWhiteSpace(message.UsingCode))
                    scriptSource.SetUsingCode(ActionsUtils.ConvertToLines(message.UsingCode));
                if (!string.IsNullOrEmpty(message.CodeAuthor + message.CodeDescription))
                    scriptSource.SetAuthorAndDescription(message.CodeAuthor, message.CodeDescription);
                if (!string.IsNullOrEmpty(message.MainCode))
                {
                    scriptSource.MainCode.UpdateLines(ActionsUtils.ReplaceCode(message.MainCode));
                }
                if (!string.IsNullOrWhiteSpace(message.FuncCode))
                {
                    scriptSource.AdditionalFunctionCode.UpdateLines(ActionsUtils.ReplaceCode(message.FuncCode));
                }
                if (!string.IsNullOrWhiteSpace(message.ClassCode))
                {
                    scriptSource.AdditionalClassCode.UpdateLines(ActionsUtils.ReplaceCode(message.ClassCode));
                }
                scriptSource.Attributes.InitSourceFromAI(message.UserName, message.Question.Trim());
            }
        }
    }
}
